package info.carl.jgdt.dao;

import info.carl.jgdt.beans.Task;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

public class TaskDaoImpl implements TaskDao{
    private List<Task> taskList;
    private String fileName;
    
    public TaskDaoImpl(String fileName){
        taskList = new ArrayList<Task>();
        this.fileName = fileName;
        loadFromFile(fileName);
    }

    /**
     * This function loads the task on the specified file name
     * @param fileName The filename to load tasks from
     **/
    public void loadFromFile(String fileName){
        this.fileName = fileName;
        try{
            BufferedReader reader = new BufferedReader(new FileReader(fileName));
            String line;
            int id = 0;
            while (( line = reader.readLine()) != null){
                line = line.trim();
                id++;
                Task task = new Task();
                task.setId(id);
                task.setContext(getContextForLine(line));
                task.setProject(getProjectForLine(line));
                task.setDescription(getDescriptionForLine(line));
                taskList.add(task);
            }
            reader.close(); //If any error occurs, will not close my reader. Must refactor here later
        }catch(FileNotFoundException e){
            e.printStackTrace();
        }catch(IOException e){
            e.printStackTrace();
        }    
    }
    
    public void delete(Task task) throws FileNotFoundException, IOException{
        taskList.remove(task);
        persist();
    }
    
    public void save(Task task) throws FileNotFoundException, IOException{
        if (task.getId().equals(0)){ //Is inserting a new task
            task.setId(genId());
            taskList.add(task);
        }else{
            int indice = taskList.indexOf(task);
            taskList.set(indice, task);
        }
        persist();
    }

    public List<Task> getTasks(List<String> projects, List<String> contexts) {
        List<Task> tasks = new ArrayList<Task>();
        for (Task task: taskList){
            if (inList(task.getProject(), projects) && inList(task.getContext(), contexts)){
                tasks.add(task);
            }
        }
        return tasks;
    }
    
    
    public Set<String> getProjects() {
        Set<String> projects = new TreeSet<String>();
        for (Task task: taskList){
            projects.add(task.getProject());
        }
        return projects;
    }
    
    
    public Set<String> getContexts() {
        Set<String> contexts = new TreeSet<String>();
        for (Task task: taskList){
            contexts.add(task.getContext());
        }
        return contexts;
    }
   
    
    private void persist() throws FileNotFoundException, IOException{
        BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));
        for (Task t: taskList){
            writer.write(t.getContext() + " " + t.getProject() + " " + t.getDescription());
            writer.newLine();
        }
        writer.close();
    }

    private Boolean inList(String line, List<String> list){
        Boolean found = false;
        for (String item: list){
            if (line.concat(" ").contains(item.concat(" "))){
                found = true;
            }
        }
        return found;
    }
    
    private String getProjectForLine(String line){
        String result = null;
        line = line.trim();
        if (line.indexOf('+') >= 0){
            line = line.substring(line.indexOf('+')).trim();
            result = line.substring(0, line.indexOf(' ')).trim();
        }
        return result;
    }
    
    private String getContextForLine(String line){
        String result = null;
        line = line.trim();
        if (line.indexOf('@') >= 0){
            line = line.substring(line.indexOf('@')).trim();
            result = line.substring(0, line.indexOf(' ')).trim();
        }
        return result;
    }
    
    private String getDescriptionForLine(String line){
        String context = getContextForLine(line);
        String project = getProjectForLine(line);
        line = line.replace(context, "");
        line = line.replace(project, "");
        return line.trim();
    }

    private Integer genId(){
        int id = 0;
        for (Task task: taskList){
            if (task.getId() > id){
                id = task.getId();
            }
        }
        return id+1;
    }
    
}
